import rooms.room as room
import random
import operator
import json


class Ddz(room.Room):
    def __init__(self, server, roomid):
        super().__init__(3, server, roomid)

    async def start(self):
        self.next = random.randint(0, self.maximum - 1)
        # maincard:主牌   mainnum:主牌数量 1-4  mainlen:连牌数量
        self.prev = {"type": "null", "num": 0, "maincard": 0, "mainnum": 0, "mainlen": 0}
        self.passcount = 2
        self.scores = [-1] * 3
        self.score = 0
        self.kuo = -1
        cards = []
        for a in range(1, 5):
            for b in range(3, 16):
                cards.append(a * 100 + b)
        cards.append(16)
        cards.append(17)
        random.shuffle(cards)
        self.board = [cards[:17], cards[17:34], cards[34:51], cards[51:]]
        for i in range(3):
            await self.players[i].send(
                json.dumps({"command": "start", "data": {"cards": self.board[i], "next": self.next}, "pid": i}))

    @room.add
    async def call(self, pid, data):
        score = data['score']
        if self.next != pid or self.kuo != -1:
            return
        if score != 0 and score <= max(self.scores):
            return
        self.scores[pid] = score
        maxscore = max(self.scores)
        await self.sendall({"command": "call", "score": score, "pid": pid})
        if -1 in self.scores and score != 3:
            self.next = (self.next + 1) % self.maximum
        else:
            if maxscore == 0:
                self.kuo = random.randint(0, self.maximum - 1)
                self.score = 4
                self.scores[self.kuo] = self.score
            else:
                self.score = maxscore
                self.kuo = self.scores.index(maxscore)
            self.board[self.kuo].extend(self.board[3])
            print(self.board)
            await self.sendall({"command": "kuo", "pid": self.kuo, "score": self.score, "cards": self.board[3]})

    @room.add
    async def act(self, pid, data):
        if pid != self.next:
            return
        cardarr = data['cards']
        for i in cardarr:
            if not i in self.board[pid]:
                return
        num = len(cardarr)
        if num == 0:
            type = "null"
        else:
            count = [0 for i in range(18)]
            for card in cardarr:
                c = card % 100
                count[c] += 1
            cards = [[] for i in range(5)]
            for i in range(18):
                if count[i] != 0:
                    cards[count[i]].append(i)
            type = "unknow"
            maincard = mainnum = mainlen = 0
            lens = [len(i) for i in cards]
            if num == 1:
                type = "1"
            elif num == 2:
                if lens[2] == 1:
                    type = "2"
                elif cards[1][0] == 16:
                    type = "rocket"
            elif num == 3:
                if lens[3] == 1:
                    type = "3"
            elif num == 4:
                if lens[4] == 1:
                    type = "boom"
                elif lens[3] == 1:
                    type = "3+1"
            elif num == 5:
                if lens[3] == 1 and lens[2] == 1:
                    type = "3+2"
                elif lens[1] == 5 and cards[1][-1] - cards[1][0] == 4 and cards[1][-1] <= 14:
                    type = "shunzi"
            elif lens[1] == num and cards[1][-1] - cards[1][0] == num - 1 and cards[1][-1] <= 14:
                type = "shunzi"
            elif num % 2 == 0 and lens[2] == num / 2 and cards[2][-1] - cards[2][0] == num / 2 - 1 and cards[2][
                -1] <= 14:
                type = "liandui"
            elif lens[4] == 1 and num == 6 and (lens[1] == 2 or lens[2] == 1):
                type = "4+1"
            elif lens[4] == 1 and num == 8 and lens[2] == 2:
                type = "4+2"
            elif lens[3] > 1:
                if lens[3] == lens[1] + lens[2] * 2 + lens[4] * 4 and cards[3][-1] - cards[3][0] == lens[3] - 1:
                    type = "3+1*n"
                    maincard = cards[3][0]
                    mainnum = 3
                    mainlen = lens[3]
                elif lens[3] == lens[2] + lens[4] * 2 and lens[1] == 0:
                    type = "3+2*n"
                    maincard = cards[3][0]
                    mainnum = 3
                    mainlen = lens[3]
                elif lens[3] - 1 == lens[1] + lens[2] * 2 + lens[4] * 4 + 3 and (
                        cards[3][-1] - cards[3][1] == lens[3] - 2 or cards[3][-2] - cards[3][0] == lens[3] - 2):
                    type = "3+1*n"
                    maincard = cards[3][0 if cards[3][1] - cards[3][0] == 1 else 1]
                    mainnum = 3
                    mainlen = lens[3] - 1
            if type == "unknow":
                return
            if maincard == 0:
                for i in range(4, 0, -1):
                    if lens[i] > 0:
                        maincard = cards[i][0]
                        mainnum = i
                        mainlen = lens[i]
                        break
        if self.passcount == 2:
            if type == "null":
                return
        elif type != "null":
            if type == "rocket":
                self.score *= 2
            elif type == "boom":
                if self.prev['type'] == "rocket":
                    return
                if self.prev['type'] == "boom":
                    if self.prev['maincard'] > maincard:
                        return
                self.score *= 2
            elif num != self.prev['num'] or type != self.prev['type'] or maincard <= self.prev['maincard']:
                return
        await self.sendall({"command": "act", "pid": pid, "cards": cardarr})
        self.next = (self.next + 1) % self.maximum
        if type == "null":
            self.passcount += 1
        else:
            self.passcount = 0
            self.prev['type'] = type
            self.prev['num'] = num
            self.prev['maincard'] = maincard
            self.prev['mainnum'] = mainnum
            self.prev['mainlen'] = mainlen
            for i in cardarr:
                self.board[pid].remove(i)
            if len(self.board[pid]) == 0:
                await self.win(pid)
        print(self.roomid, pid, cardarr)
